import os
import requests
from PySide6.QtWidgets import *
from PySide6.QtCore import *
from PySide6.QtGui import *
import random
from Box2D import b2World, b2PolygonShape, b2FixtureDef
vel_iters, pos_iters = 6, 2


class downloadGiftImg(QThread):
    def __init__(self, name, link):
        super(downloadGiftImg, self).__init__()
        self.giftName = name
        self.size, self.link = link

    def run(self):
        r = requests.get(self.link)
        img = QPixmap.fromImage(QImage.fromData(r.content)).scaled(self.size, self.size, Qt.AspectRatioMode.IgnoreAspectRatio, Qt.TransformationMode.SmoothTransformation)
        file = QFile('gift/%s.png' % self.giftName)
        file.open(QIODevice.WriteOnly)
        img.save(file, 'PNG')


class GiftPysical(QWidget):
    def __init__(self, giftMax, opacity=False, top=False):
        super(GiftPysical, self).__init__()
        self.setWindowFlag(Qt.FramelessWindowHint)
        self.giftMax = int(giftMax)
        if opacity:
            self.setAttribute(Qt.WA_TranslucentBackground)
        if top:
            self.setWindowFlag(Qt.WindowStaysOnTopHint)
        self.antiAliasing = True
        self.setWindowTitle('礼物展示')
        self.setFixedSize(1280, 720)
        self.setStyleSheet('background-color:#00d600')
        self.tick = 1 / 60
        self.world = b2World((0, 10), True)
        self.ground = self.world.CreateStaticBody(position=(-1, 72), shapes=b2PolygonShape(box=(130, 0)))
        # self.world.CreateStaticBody(position=(380, 900), shapes=b2PolygonShape(box=(10, 680)))
        # self.world.CreateStaticBody(position=(810, 900), shapes=b2PolygonShape(box=(10, 680)))
        # self.world.CreateStaticBody(position=(2500, 300), shapes=b2PolygonShape(box=(10, 1000)))
        self.world.CreateStaticBody(position=(-1, 0), shapes=b2PolygonShape(box=(0, 100)))
        self.world.CreateStaticBody(position=(128, 0), shapes=b2PolygonShape(box=(0, 100)))

        # self.bottle = QPixmap('utils/bilibili.png').scaled(1200, 1200, Qt.AspectRatioMode.IgnoreAspectRatio, Qt.TransformationMode.SmoothTransformation)
        self.pixmaps = {}
        for gift in os.listdir('gift'):
            self.pixmaps[gift[:-4]] = QPixmap('gift/%s' % gift)
        self.gifts = []
        self.giftsBody = []
        self.gifts_free = []
        self.giftsBody_free = []
        self.widgets = []
        self.timer = QTimer()
        self.timer.timeout.connect(self.update)
        self.timer.setInterval(15)
        self.timer.start()

        self.clearGiftTimer = QTimer()
        self.clearGiftTimer.setInterval(10)
        self.clearGiftTimer.timeout.connect(self.clearGift)

        self.addGift('小心心', 50, 0)
        self.addGift('辣条', 50, 0)
        self.adjustSize()

    def addGift(self, giftName, number, price):
        if giftName not in self.pixmaps:
            if giftName + '.png' in os.listdir('gift'):
                gift = QPixmap('gift/%s.png' % giftName)
                self.pixmaps[giftName] = gift
                if price > 0:
                    for _ in range(number):
                        self.gifts.append(giftName)
                        body = self.world.CreateDynamicBody(position=(random.randint(1, 127), random.randint(-20, -10)))
                        self.giftsBody.append(body.CreateCircleFixture(radius=1, density=random.uniform(0.5, 1),
                                                                       friction=1, restitution=random.uniform(0.3, 0.7)))
                else:
                    for _ in range(number):
                        self.gifts_free.append(giftName)
                        body = self.world.CreateDynamicBody(position=(random.randint(1, 127), random.randint(-20, -10)))
                        self.giftsBody_free.append(body.CreateCircleFixture(radius=1, density=random.uniform(0.5, 1),
                                                                            friction=1, restitution=random.uniform(0.3, 0.7)))
            else:
                return
        else:
            if price > 0:
                for _ in range(number):
                    self.gifts.append(giftName)
                    body = self.world.CreateDynamicBody(position=(random.randint(1, 127), random.randint(-20, -10)))
                    self.giftsBody.append(body.CreateCircleFixture(radius=1, density=random.uniform(0.5, 1),
                                                                   friction=1, restitution=random.uniform(0.3, 0.7)))
            else:
                for _ in range(number):
                    self.gifts_free.append(giftName)
                    body = self.world.CreateDynamicBody(position=(random.randint(1, 127), random.randint(-20, -10)))
                    self.giftsBody_free.append(body.CreateCircleFixture(radius=1, density=random.uniform(0.5, 1),
                                                                        friction=1, restitution=random.uniform(0.3, 0.7)))

    def setBackgroundColor(self, color):
        self.setStyleSheet('background-color:%s' % color)

    def paintEvent(self, QPaintEvent):
        self.world.Step(self.tick, vel_iters, pos_iters)
        painter = QPainter(self)
        if self.antiAliasing:
            painter.setRenderHints(QPainter.SmoothPixmapTransform)  # 抗锯齿
        index1, index2 = 0, 0
        for index1, gift in enumerate(self.giftsBody_free):
            pix = self.pixmaps[self.gifts_free[index1]]
            body = gift.body
            x, y = body.position.x * 10, body.position.y * 10
            pix_w, pix_h = pix.width() // 2, pix.height() // 2
            angle = body.angle
            painter.translate(x, y)
            painter.rotate(angle)
            painter.translate(-x, -y)
            painter.drawPixmap(x - pix_w, y - pix_h, pix)
            painter.translate(x, y)
            painter.rotate(-angle)
            painter.translate(-x, -y)

        for index2, gift in enumerate(self.giftsBody):
            pix = self.pixmaps[self.gifts[index2]]
            body = gift.body
            x, y = body.position.x * 10, body.position.y * 10
            pix_w, pix_h = pix.width() // 2, pix.height() // 2
            angle = body.angle
            painter.translate(x, y)
            painter.rotate(angle)
            painter.translate(-x, -y)
            painter.drawPixmap(x - pix_w, y - pix_h, pix)
            painter.translate(x, y)
            painter.rotate(-angle)
            painter.translate(-x, -y)

        if index1 + index2 >= self.giftMax:
            if index1 >= self.giftMax // 2:
                self.world.DestroyBody(self.giftsBody_free.pop(0).body)
                self.gifts_free.pop(0)
            else:
                self.world.DestroyBody(self.giftsBody.pop(0).body)
                self.gifts.pop(0)

    def clearGift(self):
        if self.gifts_free:
            self.world.DestroyBody(self.giftsBody_free.pop(0).body)
            self.gifts_free.pop(0)
        elif self.gifts:
            self.world.DestroyBody(self.giftsBody.pop(0).body)
            self.gifts.pop(0)
        if len(self.gifts_free) + len(self.gifts) == 0:
            self.clearGiftTimer.stop()
            self.ground = self.world.CreateStaticBody(position=(-1, 72), shapes=b2PolygonShape(box=(130, 0)))

    def mousePressEvent(self, QEvent):
        if QEvent.button() == Qt.LeftButton:
            self.mousePressToken = True
            self.startPos = QEvent.pos()
        elif QEvent.button() == Qt.RightButton:
            menu = QMenu()
            antiAliasing = menu.addAction('抗锯齿')
            if self.antiAliasing:
                antiAliasing.setIcon(self.style().standardIcon(QStyle.SP_DialogApplyButton))
            clearAll = menu.addAction('消除')
            action = menu.exec_(self.mapToGlobal(QEvent.pos()))
            # if action == addLiver:
            #     self.addLiver.emit()
            if action == antiAliasing:
                self.antiAliasing = not self.antiAliasing
            elif action == clearAll:
                self.world.DestroyBody(self.ground)
                self.clearGiftTimer.start()

    def mouseReleaseEvent(self, QEvent):
        self.mousePressToken = False

    def mouseMoveEvent(self, QEvent):
        if self.mousePressToken:
            self.move(self.pos() + (QEvent.pos() - self.startPos))
